package org.ftc.report;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;

import org.apache.commons.lang3.StringUtils;
import org.docx4j.XmlUtils;
import org.docx4j.model.fields.merge.DataFieldName;
import org.docx4j.model.fields.merge.MailMerger;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
import org.docx4j.openpackaging.parts.Part;
import org.docx4j.wml.ContentAccessor;
import org.docx4j.wml.P;
import org.docx4j.wml.Tbl;
import org.docx4j.wml.Text;
import org.docx4j.wml.Tr;
import org.joda.time.DateTime;

public class Report1 {

	public static void main(String[] args) throws Exception {
		report3();
	}

	private static void report3() throws Exception {
		File tmp = new File("D:\\ftc\\1165\\目次表1.docx");
		WordprocessingMLPackage template = WordprocessingMLPackage.load(tmp);
		// 變數

		Map<DataFieldName, String> map = new HashMap<>();
		map.put(new DataFieldName("sessionNo"), "九九九九");
		map.put(new DataFieldName("date"), "103/1/1");

		// replaceTable("COLUMN1", map2, template);
		System.out.println("===================================");
		Part part = template.getMainDocumentPart();
		List<Object> ps = getAllElementFromObject(part, P.class);
		String str = "報告事項", st1 = "報告案", st2 = "討論事項", s3 = "審議案";

		Map<String, String> map2 = new HashMap<>();
		map2.put("事項", "報告事項：");
		cloneP(template, ps, "事項", map2);
		map2.put("案", "報告案：");
		cloneP(template, ps, "案", map2);
		for (int x = 0; x < 5; x++) {
			map2 = new HashMap<>();
			map2.put("壹", "一");
			map2.put("案由", "測試案由一二三四五六七。");
			map2.put("date1", "111.1.1");
			map2.put("單位", "測試單位");
			map2.put("date2", "222.2.2");
			map2.put("委員", "三委員四五");
			cloneP(template, ps, "壹", map2);
		}
		map2 = new HashMap<>();
		map2.put("事項", "討論事項：");
		cloneP(template, ps, "事項", map2);
		map2.put("案", "審議案：");
		cloneP(template, ps, "案", map2);
		for (int x = 0; x < 5; x++) {
			map2 = new HashMap<>();
			map2.put("壹", "二");
			map2.put("案由", "測試案由一二三四五六七。");
			map2.put("date1", "111.1.1");
			map2.put("單位", "測試單位");
			map2.put("date2", "222.2.2");
			map2.put("委員", "三委員四五");
			cloneP(template, ps, "壹", map2);
		}
		String[] strs = { "事項", "案", "壹" };
		removeP(template, ps, strs);

		/*
		 * Map<String,String> map3 = new HashMap<>(); map3.put("n2", "2");
		 * map3.put("cause2", "ABCDEFG。"); map3.put("committee2", "一委員二三");
		 * map3.put("unit2", "測試單位"); map3.put("charge2", "測試承辦");
		 * map3.put("chief2", "科長一"); Map<String,String> map4 = new HashMap<>();
		 * map4.put("n2", "3"); map4.put("cause2", "測試用的案由。");
		 * map4.put("committee2", "一委員對對"); map4.put("unit2", "測試單位");
		 * map4.put("charge2", "測試承辦"); map4.put("chief2", "科長五");
		 * Map<String,String> map5 = new HashMap<>(); map5.put("n2", "4");
		 * map5.put("cause2", "測試用的案由102年1月1日。"); map5.put("committee2",
		 * "一委員三三"); map5.put("unit2", "測試單位一"); map5.put("charge2", "測試承辦");
		 * map5.put("chief2", "科長四");
		 */

		MailMerger.performMerge(template, map, true);
		// WordprocessingMLPackage output =
		// MailMerger.getConsolidatedResultCrude(template,
		// Arrays.asList(map2,map7), true);
		template.save(new java.io.File("D:\\REPORT_1.docx"));
		System.out.println("end");
	}

	private static void cloneP(WordprocessingMLPackage template, List<Object> ps, String key, Map<String, String> map)
			throws Docx4JException, JAXBException {
		P tempP = getTemplateP(ps, key);
		List<Object> content = template.getMainDocumentPart().getContent();
		content.add(cloneP(tempP, map));
	}

	private static void removeP(WordprocessingMLPackage template, List<Object> ps, String[] strs)
			throws Docx4JException, JAXBException {
		for (String key : strs) {
			P tempP = getTemplateP(ps, key);
			template.getMainDocumentPart().getContent().remove(tempP);
		}
	}

	/*
	 * private static void replaceAndCloneTable(P tempP, List<Map<String,
	 * String>> textToAdd, WordprocessingMLPackage template) throws
	 * Docx4JException, JAXBException { // 1. find the table List<Object>
	 * content = template.getMainDocumentPart().getContent(); for (Map<String,
	 * String> replacements : textToAdd) { // 2 and 3 are done in this method
	 * content.add(cloneTable(tempP, replacements)); } // 4. remove the template
	 * row content.remove(tempP); System.out.println("replace end"); }
	 */

	private static List<Object> getAllElementFromObject(Object obj, Class<?> toSearch) {

		List<Object> result = new ArrayList<Object>();
		if (obj instanceof JAXBElement)
			obj = ((JAXBElement<?>) obj).getValue();

		if (obj.getClass().equals(toSearch))
			result.add(obj);
		else if (obj instanceof ContentAccessor) {
			List<?> children = ((ContentAccessor) obj).getContent();
			for (Object child : children) {
				result.addAll(getAllElementFromObject(child, toSearch));
			}

		}
		return result;
	}

	private static P getTemplateP(List<Object> ps, String templateKey) throws Docx4JException, JAXBException {
		System.out.println("table size:" + ps.size());
		for (Iterator<Object> iterator = ps.iterator(); iterator.hasNext();) {
			Object p = iterator.next();
			System.out.println("=====================================");
			List<?> textElements = getAllElementFromObject(p, Text.class);
			for (Object text : textElements) {
				Text textElement = (Text) text;
				System.out.println("col value:" + textElement.getValue());
				if (StringUtils.equals(textElement.getValue(), templateKey))
					return (P) p;
			}
		}

		return null;
	}

	private static P cloneP(P p, Map<String, String> replacements) {
		System.out.println("begin clone");

		P tempP = (P) XmlUtils.deepCopy(p);
		List<?> textElements = getAllElementFromObject(tempP, Text.class);
		System.out.println("textElements size:" + textElements.size());
		for (Object object : textElements) {
			Text text = (Text) object;
			System.out.println("textValue:" + text.getValue());
			String replacementValue = (String) replacements.get(text.getValue());
			if (replacementValue != null) {
				System.out.println("replacement:" + replacementValue);
				text.setValue(replacementValue);
			}
		}
		return tempP;
	}

}
